#pragma once

#include <vector>
#include <string>
#include <cstdint>
#include <cstring>
#include <stdexcept>
#include <type_traits> // for is_integral_v, is_same_v

#ifdef _WIN32
#include <winsock2.h>
#else
#include <arpa/inet.h>
#endif

class Serializer {
public:
    const std::vector<char>& get_buffer() const { return buffer_; }

    // --- 统一的写入模板函数 ---
    template<typename T>
    void write(const T& value) {
        // 使用 if constexpr 来区分不同类型
        if constexpr (std::is_same_v<T, std::string>) {
            // 情况1: 是 std::string
            write_integral(static_cast<uint32_t>(value.length()));
            buffer_.insert(buffer_.end(), value.begin(), value.end());
        } else if constexpr (requires { typename T::value_type; typename T::iterator; }) {
            // 情况2: 是一个容器 (有 value_type 和 iterator)
            write_integral(static_cast<uint32_t>(value.size()));
            for (const auto& item : value) {
                write(item); // 递归写入每个元素
            }
        } else {
            // 情况3: 是其他基本类型 (int, bool, float, enum, struct等)
            write_integral(value);
        }
    }

private:
    std::vector<char> buffer_;

    // 辅助函数，专门处理整数和字节序
    template<typename T>
    void write_integral(const T& value) {
        if constexpr (std::is_integral_v<T> && sizeof(T) > 1) {
            T net_value;
            if constexpr (sizeof(T) == 2) net_value = htons(static_cast<uint16_t>(value));
            else if constexpr (sizeof(T) == 4) net_value = htonl(static_cast<uint32_t>(value));
            else net_value = value; // 64位暂不处理
            buffer_.insert(buffer_.end(), (const char*)&net_value, (const char*)&net_value + sizeof(T));
        } else { // 字节(bool, char), 浮点数等直接写入
            buffer_.insert(buffer_.end(), (const char*)&value, (const char*)&value + sizeof(T));
        }
    }
};


// --- Deserializer: 从字节流读取数据 ---
class Deserializer {
public:
    Deserializer(const char* data, size_t size) : cursor_(data), end_(data + size) {}

    // --- 统一的读取模板函数 ---
    template<typename T>
    void read(T& value) {
        if constexpr (std::is_same_v<T, std::string>) {
            // 情况1: 是 std::string
            uint32_t length;
            read_integral(length);
            if (cursor_ + length > end_) throw std::out_of_range("Buffer underflow for string content.");
            value.assign(cursor_, length);
            cursor_ += length;
        } else if constexpr (requires { typename T::value_type; typename T::iterator; }) {
            // 情况2: 是一个容器
            uint32_t size;
            read_integral(size);
            value.clear();
            if constexpr (requires { value.reserve(size); }) value.reserve(size);
            for (uint32_t i = 0; i < size; ++i) {
                typename T::value_type item;
                read(item); // 递归读取
                if constexpr (requires { value.emplace_back(std::move(item)); }) value.emplace_back(std::move(item));
                else value.insert(value.end(), std::move(item));
            }
        } else {
            // 情况3: 是其他基本类型
            read_integral(value);
        }
    }

private:
    const char* cursor_;
    const char* end_;

    // 辅助函数，专门处理整数和字节序
    template<typename T>
    void read_integral(T& value) {
        if (cursor_ + sizeof(T) > end_) throw std::out_of_range("Buffer underflow for value.");
        memcpy(&value, cursor_, sizeof(T));
        cursor_ += sizeof(T);
        
        if constexpr (std::is_integral_v<T> && sizeof(T) > 1) {
            if constexpr (sizeof(T) == 2) value = ntohs(value);
            else if constexpr (sizeof(T) == 4) value = ntohl(value);
            // 64位暂不处理
        }
    }
};